import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

enum WXTextOverflow { ellipsisStart, ellipsisMiddle, ellipsisEnd, clip, fade, visible }

class WXOverFlowTextWidget extends StatefulWidget {
  final String text;
  final TextStyle style;
  final WXTextOverflow overflow;
  final TextDirection textDirection;
  final double textScaleFactor;

  WXOverFlowTextWidget(
      {Key key,
      @required this.text,
      this.style = const TextStyle(color: Color(0xFF212121),fontSize: 14.0),
      this.overflow = WXTextOverflow.clip,
      this.textDirection,
      this.textScaleFactor = 1.0})
      : super(key: key);

  @override
  _OverFlowTextState createState() => _OverFlowTextState();
}

class _OverFlowTextState extends State<WXOverFlowTextWidget> {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (_, boxConstraint) {
      return Text(
        _calculateFinalText(boxConstraint.maxWidth, widget.text, widget.style.fontSize ?? 14.0),
        style: widget.style ??
            TextStyle(color: widget.style.color ?? Colors.grey[900], fontSize: widget.style.fontSize ?? 14.0),
        maxLines: 1,
        overflow: _getOverflow(widget.overflow),
        textAlign: TextAlign.center,
        textDirection: widget.textDirection,
        textScaleFactor: widget.textScaleFactor,
      );
    });
  }

  ///获取对应的overflow类型
  TextOverflow _getOverflow(WXTextOverflow overflow) {
    TextOverflow textOverflow;
    if (overflow == WXTextOverflow.ellipsisEnd) {
      textOverflow = TextOverflow.ellipsis;
    } else if (overflow == WXTextOverflow.ellipsisMiddle || overflow == WXTextOverflow.clip) {
      textOverflow = TextOverflow.clip;
    } else if (overflow == WXTextOverflow.visible) {
      textOverflow = TextOverflow.visible;
    } else if (overflow == WXTextOverflow.fade) {
      textOverflow = TextOverflow.fade;
    }
    return textOverflow;
  }

  /// 计算文本的宽度
  double calculateTextLength(double maxWidth, String value, double fontSize) {
    final constraints = BoxConstraints(
      maxWidth: maxWidth,
      minHeight: 0.0,
      minWidth: 0.0,
    );

    RenderParagraph renderParagraph = RenderParagraph(
      TextSpan(
        text: value,
        style: TextStyle(
          fontSize: fontSize,
        ),
      ),
      textDirection: TextDirection.ltr,
      maxLines: 1,
    );
    renderParagraph.layout(constraints);
    double textLength = renderParagraph.computeMinIntrinsicWidth(fontSize).ceilToDouble();
    return textLength * widget.textScaleFactor;
  }

  /// 获取省略号起始index
  int getStartIndex(double maxTextLength, double parentWidth, int textLength) {
    double ellipsisWidth = calculateTextLength(parentWidth, "...", widget.style.fontSize ?? 14.0);
    double perWidth = maxTextLength / textLength;
    double half = parentWidth / 2;
    double index = (half - ellipsisWidth) / perWidth;
    print(
        "perWidth=======>$ellipsisWidth======>${1.5 * perWidth}======>$perWidth======>$maxTextLength=======>$parentWidth");
    return widget.overflow == WXTextOverflow.ellipsisStart ? 0 : index.toInt();
  }

  ///获取省略号结束的index
  int getEndIndex(double maxTextLength, String text, double maxWidth) {
    double ellipsisWidth = calculateTextLength(maxWidth, "...", widget.style.fontSize ?? 14.0);

    int endIndex = 0;
    if (widget.overflow == WXTextOverflow.ellipsisStart) {
      double perWidth = maxTextLength / text.length;
      double restWidth = maxWidth - ellipsisWidth;

      int restLength = restWidth ~/ perWidth;
      endIndex = text.length - restLength;
    } else {
      String halfText = text.substring(0, getStartIndex(maxTextLength, maxWidth, text.length));
      double textWidth = calculateTextLength(maxWidth, halfText, widget.style.fontSize ?? 14.0);

      double perWidth = maxTextLength / text.length;
      double restWidth = maxWidth - textWidth - ellipsisWidth;

      int restLength = restWidth ~/ perWidth;

      endIndex = text.length - restLength;
    }
    return endIndex;
  }

  /// 计算获取最终文本
  String _calculateFinalText(double maxWidth, String text, double fontSize) {
    double maxTextLength = calculateTextLength(maxWidth, widget.text, widget.style.fontSize ?? 14.0);

    if ((widget.overflow != WXTextOverflow.ellipsisMiddle && widget.overflow != WXTextOverflow.ellipsisStart) ||
        maxTextLength <= maxWidth) return text;

    int startIndex = getStartIndex(maxTextLength, maxWidth, text.length);
    int endIndex = getEndIndex(maxTextLength, text, maxWidth);
    return text.replaceRange(startIndex, endIndex, "...");
  }
}
